package com.lanmao.blog.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lanmao.blog.entity.User;
import com.lanmao.blog.exception.CodeException;
import com.lanmao.blog.exception.PhoneErrorException;
import com.lanmao.blog.service.impl.CustomUserServiceImpl;
import com.lanmao.blog.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.*;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Component
public class SmsCodeAuthenticationConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
    @Autowired
    private CustomUserServiceImpl customUserService;
    @Autowired SmsCodeAuthenticationFilter filter;
    @Override
    public void configure(HttpSecurity builder) throws Exception {
        filter.setAuthenticationManager(builder.getSharedObject(AuthenticationManager.class));
        filter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                response.setContentType("application/json;charset=utf-8");
                PrintWriter out = response.getWriter();
                User user = (User)authentication.getPrincipal();
                user.setPassword(null);
                R ok = R.ok().data("data",user).message("登录成功！");
                String s = new ObjectMapper().writeValueAsString(ok);
                //把字符串写出去
                out.write(s);
                out.flush();
                out.close();
            }
        });
        filter.setAuthenticationFailureHandler(new AuthenticationFailureHandler() {
            @Override
            public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse resp, AuthenticationException exception) throws IOException, ServletException {
                resp.setContentType("application/json;charset=utf-8");
                PrintWriter out = resp.getWriter();
                R respBean = R.error().message("登录失败！");
                if(exception instanceof LockedException) {
                    respBean.message("账户被锁定，请联系管理员！");
                }
                else if (exception instanceof CodeException){
                    respBean.message(exception.getMessage());
                }
                else if (exception instanceof PhoneErrorException){
                    respBean.message(exception.getMessage());
                }
                out.write(new ObjectMapper().writeValueAsString(respBean));
                out.flush();
                out.close();
            }
        });
        // 2. 初始化 SmsCodeAuthenticationProvider
        SmsCodeAuthenticationProvider provider = new SmsCodeAuthenticationProvider();
        provider.setUserDetailsService(customUserService);
        // 3. 将设置完毕的 Filter 与 Provider 添加到配置中，将自定义的 Filter 加到 UsernamePasswordAuthenticationFilter 之前
        builder.authenticationProvider(provider).addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);
    }
}
